<script setup lang="ts">
import { h, ref, reactive, onMounted } from 'vue'
import { NModal, NCard, NForm, NSpace, NFormItem, NUpload, NUploadDragger, NInput, NButton, NIcon, NText, NDataTable, NPagination, NPopconfirm, useNotification, useDialog } from 'naive-ui'
import type { UploadCustomRequestOptions, DataTableColumns } from 'naive-ui'
import http from '@/tools/http'
import { useUserStore } from '@/stores/userStore'
import { CloudUploadOutlined } from '@vicons/antd'

const userStore = useUserStore()
const notification = useNotification()
const dialog = useDialog()

type RowData = {
    fileId: string
    fileStorageType: string
    fileName?: string
    fileType?: string
    fileLocation?: string
    md5: string
    uploadTime: string
    uploadUser?: string
}

const staticFileInfoTableColumns: DataTableColumns<RowData> = [
    {
        type: 'selection',
        width: 40
    }, {
        title: "文件md5",
        key: "md5",
        width: 280
    }, {
        title: "文件名称",
        key: "fileName",
        width: 150,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "文件类型",
        key: "fileType",
        width: 80,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "文件存储地址",
        key: "fileLocation",
        width: 240,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "上传时间",
        key: "uploadTime",
        width: 159
    }, {
        title: "上传人",
        key: "uploadUser",
        width: 100
    }, {
        title: "操作",
        key: "actions",
        width: 132,
        fixed: 'right',
        render(rowData: RowData, rowIndex: number) {
            return h(
                NSpace, null,
                () => [
                    h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => viewResource(rowData)
                        },
                        { default: () => "查看" }
                    ),
                    userStore.hasAuth("static-file-manage:delete") ? h(
                        NPopconfirm,
                        {
                            onPositiveClick: (e: MouseEvent) => deleteStaticFileInfo()
                        },
                        {
                            trigger: () => {
                                return h(
                                    NButton,
                                    {
                                        size: "small",
                                        onclick: () => openDeleteStaticFileInfo(rowData)
                                    },
                                    { default: () => "删除" }
                                )
                            },
                            default: () => { return "确认删除？" }
                        }
                    ) : null
                ]
            )
        }
    }
]

const staticFileInfoData = reactive<any>({
    list: [],
    pageNum: 1,
    pageSize: 10,
    pages: 1,
    total: 0
})

const staticFileInfoSearchFormValue = reactive({
    pageNum: 1,
    pageSize: 10,
    fileName: "",
    fileType: "",
    uploadUser: ""
})

const visiable = ref<boolean>(false)
const formData = reactive<RowData>({
    fileId: "",
    fileStorageType: "",
    fileName: "",
    fileType: "",
    fileLocation: "",
    md5: "",
    uploadTime: "",
    uploadUser: ""
})
const selectedRowKeys = ref<Array<string | number>>([])

onMounted(() => {
    pageStaticFileInfo()
})

function handleCheck(keys: Array<string | number>, rows: object[], meta: { row: object | undefined, action: 'check' | 'uncheck' | 'checkAll' | 'uncheckAll' }) {
    selectedRowKeys.value = keys
}

function pageNumChange(pageNum: number) {
    staticFileInfoSearchFormValue.pageNum = pageNum
    pageStaticFileInfo()
}

function pageSizeChange(pageSize: number) {
    staticFileInfoSearchFormValue.pageSize = pageSize
    pageStaticFileInfo()
}

function openUploadFile() {
    visiable.value = true
}

function openDeleteStaticFileInfo(row: RowData) {
    formData.fileId = row.fileId
    formData.fileName = row.fileName
    formData.fileType = row.fileType
    formData.fileLocation = row.fileLocation
    formData.uploadTime = row.uploadTime
    formData.uploadUser = row.uploadUser
}

function viewResource(row: RowData) {
    http.post("/static/file/url", row).then(({ data }) => {
        if (data.code === "0") {
            window.open(window.location.origin + "/api" + data.data)
        }
    })
}

function pageStaticFileInfo() {
    http.post("/static/file/page", staticFileInfoSearchFormValue).then(({ data }) => {
        if (data.code === "0") {
            staticFileInfoData.pageNum = data.data.pageNum
            staticFileInfoData.pageSize = data.data.pageSize
            staticFileInfoData.pages = data.data.pages
            staticFileInfoData.total = data.data.total
            staticFileInfoData.list.length = 0
            for (let i = 0; i < data.data.list.length; i++) {
                staticFileInfoData.list.push(data.data.list[i])
            }
        }
    })
}

function uploadFile({ file, data, headers, withCredentials, action, onFinish, onError, onProgress }: UploadCustomRequestOptions) {
    const request = new FormData()
    request.append('file', file.file as File, file.file?.name)
    http.post("/static/file/upload", request, {
        headers: {
            'Content-Type': 'multipart/form-data;charset=UTF-8'
        },
        onUploadProgress: function (uploadEvent) {
            if (uploadEvent.total) {
                const progress = uploadEvent.loaded / uploadEvent.total * 100
                onProgress({ percent: Math.ceil(progress) })
            }
        }
    }).then(({ data }) => {
        notification['success']({
            content: '上传成功',
            meta: `${data.msg}`,
            duration: 2500,
            keepAliveOnHover: true
        })
        visiable.value = false
        pageStaticFileInfo()
        onFinish()
    })
}

function batchDeleteFile() {
    dialog.warning({
        title: '批量删除文件',
        content: '确定删除已选择的文件吗？',
        positiveText: '确定',
        negativeText: '取消',
        onPositiveClick: () => {
            const request = selectedRowKeys.value
            http.post("/static/file/batch/delete", request).then(({ data }) => {
                if (data.code === "0") {
                    notification['success']({
                        content: '删除成功',
                        meta: `${data.msg}`,
                        duration: 2500,
                        keepAliveOnHover: true
                    })
                    pageStaticFileInfo()
                }
            })
        }
    })
}

function deleteStaticFileInfo() {
    http.post("/static/file/delete", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '删除成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageStaticFileInfo()
        }
    })
}
</script>

<template>
    <div id="flame-container">
        <div class="search">
            <n-form :model="staticFileInfoSearchFormValue" inline label-placement="left">
                <n-form-item label="文件名称" path="fileName">
                    <n-input v-model:value="staticFileInfoSearchFormValue.fileName" placeholder="请输入文件名称" clearable />
                </n-form-item>
                <n-form-item label="文件类型" path="fileType">
                    <n-input v-model:value="staticFileInfoSearchFormValue.fileType" placeholder="请输入文件类型" clearable />
                </n-form-item>
                <n-form-item label="上传人" path="uploadUser">
                    <n-input v-model:value="staticFileInfoSearchFormValue.uploadUser" placeholder="请输入上传人" clearable />
                </n-form-item>
                <n-form-item>
                    <n-button attr-type="button" @click="pageStaticFileInfo()">查询</n-button>
                </n-form-item>
            </n-form>
        </div>
        <div class="btn-group">
            <n-space>
                <n-button @click="openUploadFile()">上传文件</n-button>
                <n-button v-if="userStore.hasAuth('static-file-manage:batch-delete')" attr-type="button"
                    :disabled="selectedRowKeys.length === 0" @click="batchDeleteFile()">批量删除</n-button>
            </n-space>
        </div>
        <div class="data-table">
            <n-data-table :scroll-x="1181" :scrollbar-props="{ trigger: 'none' }" style="height:100%" flex-height
                :row-key="(row: RowData) => row.fileId" :columns="staticFileInfoTableColumns"
                :data="staticFileInfoData.list" :bordered="false" :on-update-checked-row-keys="handleCheck" />
        </div>
        <div class="pagination">
            <n-pagination style="float:right" v-model:page="staticFileInfoData.pageNum"
                :page-size="staticFileInfoData.pageSize" :item-count="staticFileInfoData.total"
                :page-sizes="[5, 10, 30, 50, 100]" :on-update-page="pageNumChange" :on-update-page-size="pageSizeChange"
                show-quick-jumper show-size-picker />
        </div>
    </div>
    <n-modal v-model:show="visiable">
        <n-card style="width: 400px" title="上传文件">
            <n-upload :custom-request="uploadFile">
                <n-upload-dragger>
                    <div style="margin-bottom: 12px">
                        <n-icon size="48" :depth="3">
                            <CloudUploadOutlined />
                        </n-icon>
                    </div>
                    <n-text style="font-size: 16px">
                        点击或者拖动文件到该区域来上传
                    </n-text>
                </n-upload-dragger>
            </n-upload>
        </n-card>
    </n-modal>
</template>

<style scoped>
.display-flex-end {
    display: flex;
    width: 100%;
    justify-content: flex-end;
}
</style>